using System.Diagnostics;
using MassTransit;
using WeatherSystem.API.Configurations;
using WeatherSystem.API.Services;

namespace WeatherSystem.API.Services.MessageQueue
{
    /// <summary>
    /// 天气数据采集任务消费者
    /// </summary>
    public class WeatherDataCollectionTaskConsumer : IConsumer<WeatherDataCollectionTask>
    {
        private readonly IWeatherService _weatherService;
        private readonly IBusinessMetricsService _metricsService;
        private readonly ILogger<WeatherDataCollectionTaskConsumer> _logger;

        public WeatherDataCollectionTaskConsumer(
            IWeatherService weatherService,
            IBusinessMetricsService metricsService,
            ILogger<WeatherDataCollectionTaskConsumer> logger)
        {
            _weatherService = weatherService;
            _metricsService = metricsService;
            _logger = logger;
        }

        public async Task Consume(ConsumeContext<WeatherDataCollectionTask> context)
        {
            var task = context.Message;
            using var activity = _metricsService.StartActivity("consume_weather_collection_task");
            activity?.SetTag("task.id", task.TaskId);
            activity?.SetTag("task.city_count", task.CityIds.Length);

            try
            {
                _logger.LogInformation("开始处理天气数据采集任务: {TaskId}, 城市数量: {CityCount}", 
                    task.TaskId, task.CityIds.Length);

                var successCount = 0;
                var failureCount = 0;

                foreach (var cityId in task.CityIds)
                {
                    try
                    {
                        // 这里应该调用实际的数据采集逻辑
                        // 目前使用模拟数据
                        await Task.Delay(100); // 模拟处理时间
                        
                        _metricsService.RecordWeatherDataCollected(cityId, task.Source);
                        successCount++;
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "城市 {CityId} 数据采集失败", cityId);
                        failureCount++;
                    }
                }

                _logger.LogInformation("天气数据采集任务完成: {TaskId}, 成功: {SuccessCount}, 失败: {FailureCount}",
                    task.TaskId, successCount, failureCount);

                activity?.SetStatus(ActivityStatusCode.Ok);
                activity?.SetTag("task.success_count", successCount);
                activity?.SetTag("task.failure_count", failureCount);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "处理天气数据采集任务失败: {TaskId}", task.TaskId);
                activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
                throw;
            }
        }
    }

    /// <summary>
    /// 批量数据处理任务消费者
    /// </summary>
    public class BatchDataProcessingTaskConsumer : IConsumer<BatchDataProcessingTask>
    {
        private readonly IBusinessMetricsService _metricsService;
        private readonly ILogger<BatchDataProcessingTaskConsumer> _logger;

        public BatchDataProcessingTaskConsumer(
            IBusinessMetricsService metricsService,
            ILogger<BatchDataProcessingTaskConsumer> logger)
        {
            _metricsService = metricsService;
            _logger = logger;
        }

        public async Task Consume(ConsumeContext<BatchDataProcessingTask> context)
        {
            var task = context.Message;
            using var activity = _metricsService.StartActivity("consume_batch_processing_task");
            activity?.SetTag("task.id", task.TaskId);
            activity?.SetTag("task.operation_type", task.OperationType);
            activity?.SetTag("task.target_count", task.TargetIds.Length);

            try
            {
                _logger.LogInformation("开始处理批量数据处理任务: {TaskId}, 操作类型: {OperationType}, 目标数量: {TargetCount}",
                    task.TaskId, task.OperationType, task.TargetIds.Length);

                var batches = task.TargetIds.Chunk(task.BatchSize);
                var processedCount = 0;

                foreach (var batch in batches)
                {
                    try
                    {
                        // 这里应该调用实际的批量处理逻辑
                        await Task.Delay(200); // 模拟处理时间
                        processedCount += batch.Length;
                        
                        _logger.LogDebug("批量处理进度: {TaskId}, 已处理: {ProcessedCount}/{TotalCount}",
                            task.TaskId, processedCount, task.TargetIds.Length);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "批量处理失败: {TaskId}, 批次大小: {BatchSize}", 
                            task.TaskId, batch.Length);
                    }
                }

                _logger.LogInformation("批量数据处理任务完成: {TaskId}, 已处理: {ProcessedCount}",
                    task.TaskId, processedCount);

                activity?.SetStatus(ActivityStatusCode.Ok);
                activity?.SetTag("task.processed_count", processedCount);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "处理批量数据处理任务失败: {TaskId}", task.TaskId);
                activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
                throw;
            }
        }
    }

    /// <summary>
    /// 数据导出任务消费者
    /// </summary>
    public class DataExportTaskConsumer : IConsumer<DataExportTask>
    {
        private readonly IExportService _exportService;
        private readonly IBusinessMetricsService _metricsService;
        private readonly ILogger<DataExportTaskConsumer> _logger;

        public DataExportTaskConsumer(
            IExportService exportService,
            IBusinessMetricsService metricsService,
            ILogger<DataExportTaskConsumer> logger)
        {
            _exportService = exportService;
            _metricsService = metricsService;
            _logger = logger;
        }

        public async Task Consume(ConsumeContext<DataExportTask> context)
        {
            var task = context.Message;
            using var activity = _metricsService.StartActivity("consume_data_export_task");
            activity?.SetTag("task.id", task.TaskId);
            activity?.SetTag("task.export_type", task.ExportType);
            activity?.SetTag("task.data_type", task.DataType);

            try
            {
                _logger.LogInformation("开始处理数据导出任务: {TaskId}, 导出类型: {ExportType}, 数据类型: {DataType}",
                    task.TaskId, task.ExportType, task.DataType);

                byte[] exportData;
                var recordCount = 0;

                switch (task.DataType.ToLower())
                {
                    case "weather":
                        if (task.ExportType.ToLower() == "excel")
                        {
                            exportData = await _exportService.ExportWeatherDataToExcelAsync(
                                task.Filters.ContainsKey("cityId") ? task.Filters["cityId"]?.ToString() : null,
                                task.Filters.ContainsKey("startDate") ? task.Filters["startDate"]?.ToString() : null,
                                task.Filters.ContainsKey("endDate") ? task.Filters["endDate"]?.ToString() : null,
                                task.Columns.Length > 0 ? task.Columns : null);
                        }
                        else
                        {
                            exportData = await _exportService.ExportWeatherDataToCsvAsync(
                                task.Filters.ContainsKey("cityId") ? task.Filters["cityId"]?.ToString() : null,
                                task.Filters.ContainsKey("startDate") ? task.Filters["startDate"]?.ToString() : null,
                                task.Filters.ContainsKey("endDate") ? task.Filters["endDate"]?.ToString() : null,
                                task.Columns.Length > 0 ? task.Columns : null);
                        }
                        break;

                    case "cities":
                        if (task.ExportType.ToLower() == "excel")
                        {
                            exportData = await _exportService.ExportCitiesToExcelAsync();
                        }
                        else
                        {
                            exportData = await _exportService.ExportCitiesToCsvAsync();
                        }
                        break;

                    case "statistics":
                        if (task.ExportType.ToLower() == "excel")
                        {
                            exportData = await _exportService.ExportStatisticsToExcelAsync(
                                task.Filters.ContainsKey("cityId") ? task.Filters["cityId"]?.ToString() : null,
                                task.Filters.ContainsKey("startDate") ? task.Filters["startDate"]?.ToString() : null,
                                task.Filters.ContainsKey("endDate") ? task.Filters["endDate"]?.ToString() : null);
                        }
                        else
                        {
                            exportData = await _exportService.ExportStatisticsToCsvAsync(
                                task.Filters.ContainsKey("cityId") ? task.Filters["cityId"]?.ToString() : null,
                                task.Filters.ContainsKey("startDate") ? task.Filters["startDate"]?.ToString() : null,
                                task.Filters.ContainsKey("endDate") ? task.Filters["endDate"]?.ToString() : null);
                        }
                        break;

                    default:
                        throw new ArgumentException($"不支持的数据类型: {task.DataType}");
                }

                // 这里应该将导出的数据保存到文件系统或云存储
                // 并通过回调URL通知客户端完成状态
                
                _metricsService.RecordDataExport(task.ExportType, recordCount, task.UserId);
                
                _logger.LogInformation("数据导出任务完成: {TaskId}, 导出大小: {DataSize} bytes",
                    task.TaskId, exportData.Length);

                activity?.SetStatus(ActivityStatusCode.Ok);
                activity?.SetTag("export.data_size", exportData.Length);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "处理数据导出任务失败: {TaskId}", task.TaskId);
                activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
                throw;
            }
        }
    }

    /// <summary>
    /// 告警通知消费者
    /// </summary>
    public class AlertNotificationConsumer : IConsumer<AlertNotificationMessage>
    {
        private readonly IBusinessMetricsService _metricsService;
        private readonly ILogger<AlertNotificationConsumer> _logger;

        public AlertNotificationConsumer(
            IBusinessMetricsService metricsService,
            ILogger<AlertNotificationConsumer> logger)
        {
            _metricsService = metricsService;
            _logger = logger;
        }

        public async Task Consume(ConsumeContext<AlertNotificationMessage> context)
        {
            var notification = context.Message;
            using var activity = _metricsService.StartActivity("consume_alert_notification");
            activity?.SetTag("alert.id", notification.AlertId);
            activity?.SetTag("alert.type", notification.AlertType);
            activity?.SetTag("alert.severity", notification.Severity);

            try
            {
                _logger.LogInformation("处理告警通知: {AlertId}, 类型: {AlertType}, 严重程度: {Severity}",
                    notification.AlertId, notification.AlertType, notification.Severity);

                // 根据通知渠道发送告警
                foreach (var channel in notification.Channels)
                {
                    switch (channel.ToLower())
                    {
                        case "email":
                            await SendEmailNotification(notification);
                            break;
                        case "sms":
                            await SendSmsNotification(notification);
                            break;
                        case "webhook":
                            await SendWebhookNotification(notification);
                            break;
                        default:
                            _logger.LogWarning("未知的通知渠道: {Channel}", channel);
                            break;
                    }
                }

                activity?.SetStatus(ActivityStatusCode.Ok);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "处理告警通知失败: {AlertId}", notification.AlertId);
                activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
                throw;
            }
        }

        private async Task SendEmailNotification(AlertNotificationMessage notification)
        {
            // 邮件通知实现
            _logger.LogInformation("发送邮件告警通知: {AlertId} - {Title}", notification.AlertId, notification.Title);
            await Task.Delay(50); // 模拟发送时间
        }

        private async Task SendSmsNotification(AlertNotificationMessage notification)
        {
            // 短信通知实现
            _logger.LogInformation("发送短信告警通知: {AlertId} - {Title}", notification.AlertId, notification.Title);
            await Task.Delay(100); // 模拟发送时间
        }

        private async Task SendWebhookNotification(AlertNotificationMessage notification)
        {
            // Webhook通知实现
            _logger.LogInformation("发送Webhook告警通知: {AlertId} - {Title}", notification.AlertId, notification.Title);
            await Task.Delay(200); // 模拟发送时间
        }
    }

    /// <summary>
    /// 系统事件消费者
    /// </summary>
    public class SystemEventConsumer : IConsumer<SystemEventMessage>
    {
        private readonly IBusinessMetricsService _metricsService;
        private readonly ILogger<SystemEventConsumer> _logger;

        public SystemEventConsumer(
            IBusinessMetricsService metricsService,
            ILogger<SystemEventConsumer> logger)
        {
            _metricsService = metricsService;
            _logger = logger;
        }

        public async Task Consume(ConsumeContext<SystemEventMessage> context)
        {
            var eventMessage = context.Message;
            using var activity = _metricsService.StartActivity("consume_system_event");
            activity?.SetTag("event.id", eventMessage.EventId);
            activity?.SetTag("event.type", eventMessage.EventType);
            activity?.SetTag("event.source", eventMessage.Source);

            try
            {
                _logger.LogInformation("处理系统事件: {EventId}, 类型: {EventType}, 来源: {Source}",
                    eventMessage.EventId, eventMessage.EventType, eventMessage.Source);

                // 根据事件类型执行相应的处理逻辑
                switch (eventMessage.EventType.ToLower())
                {
                    case "user.login":
                        await HandleUserLoginEvent(eventMessage);
                        break;
                    case "data.collection.completed":
                        await HandleDataCollectionCompletedEvent(eventMessage);
                        break;
                    case "system.error":
                        await HandleSystemErrorEvent(eventMessage);
                        break;
                    case "performance.degradation":
                        await HandlePerformanceDegradationEvent(eventMessage);
                        break;
                    default:
                        _logger.LogDebug("未处理的系统事件类型: {EventType}", eventMessage.EventType);
                        break;
                }

                activity?.SetStatus(ActivityStatusCode.Ok);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "处理系统事件失败: {EventId}", eventMessage.EventId);
                activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
                throw;
            }
        }

        private async Task HandleUserLoginEvent(SystemEventMessage eventMessage)
        {
            _logger.LogInformation("用户登录事件: {UserId}", eventMessage.UserId);
            await Task.CompletedTask;
        }

        private async Task HandleDataCollectionCompletedEvent(SystemEventMessage eventMessage)
        {
            _logger.LogInformation("数据采集完成事件: {Message}", eventMessage.Message);
            await Task.CompletedTask;
        }

        private async Task HandleSystemErrorEvent(SystemEventMessage eventMessage)
        {
            _logger.LogWarning("系统错误事件: {Message}", eventMessage.Message);
            await Task.CompletedTask;
        }

        private async Task HandlePerformanceDegradationEvent(SystemEventMessage eventMessage)
        {
            _logger.LogWarning("性能降级事件: {Message}", eventMessage.Message);
            await Task.CompletedTask;
        }
    }
}